package com.hd.trans.share

import android.util.Log
import com.google.gson.Gson
import com.google.gson.GsonBuilder
import com.google.gson.TypeAdapter
import com.google.gson.reflect.TypeToken
import com.google.gson.stream.JsonReader
import com.google.gson.stream.JsonToken
import com.google.gson.stream.JsonWriter
import okhttp3.MediaType.Companion.toMediaTypeOrNull
import okhttp3.RequestBody
import okhttp3.RequestBody.Companion.toRequestBody
import java.io.IOException
import java.util.*

/**
 * @author       qianjujun
 * @email        qianjujun@163.com
 * @createTime  2021/1/10 17:57
 * @describe
 */
object ConvertObjectToMap {

    private val gson: Gson by lazy {
        GsonBuilder().registerTypeAdapter(object : TypeToken<TreeMap<String?, Any?>?>() {}.type, GsonTypeAdapter()).create()
    }
    private fun toJson(data: Any): Any {

        var isString = data is String

        Log.d("TAG", "toJson() called with: data = $data-----$isString")

        return when (data) {
            is Long -> data
            is String -> data
            is Int -> data
            is Boolean -> data
            is Float -> data.toInt()
            is Double -> data.toInt()
            else -> gson.toJson(data)
        }
    }

    private fun secretData(data: TreeMap<String, Any>): RequestBody {
        var jsonBuild = StringBuilder()
        data.forEach {
            jsonBuild.append("&").append(it.key).append("=").append(toJson(it.value))
        }
        jsonBuild.deleteCharAt(0)
        jsonBuild.append("hUuPd20171206LuOnD")
        var datasign = Md5Util.getMD5(jsonBuild.toString())

        data["datasign"] = datasign
        val json = gson.toJson(data)

        return json.toRequestBody("application/json; charset=utf-8".toMediaTypeOrNull())
    }


    fun <T : Any> toRequestBody(data: T): RequestBody {
        val json = gson.toJson(data)
        var map: TreeMap<String, Any> = gson.fromJson(json,
                object : TypeToken<TreeMap<String, Any>>() {}.type)
        return secretData(map)
    }


}



object GetGson{

}

internal class GsonTypeAdapter : TypeAdapter<Any?>() {
    @Throws(IOException::class)
    override fun read(`in`: JsonReader): Any? {
        // 反序列化
        val token = `in`.peek()
        return when (token) {
            JsonToken.BEGIN_ARRAY -> {
                val list: MutableList<Any?> = ArrayList()
                `in`.beginArray()
                while (`in`.hasNext()) {
                    list.add(read(`in`))
                }
                `in`.endArray()
                list
            }
            JsonToken.BEGIN_OBJECT -> {
                val map: MutableMap<String, Any?> = TreeMap()
                `in`.beginObject()
                while (`in`.hasNext()) {
                    map[`in`.nextName()] = read(`in`)
                }
                `in`.endObject()
                map
            }
            JsonToken.STRING -> `in`.nextString()
            JsonToken.NUMBER -> {
                /**
                 * 改写数字的处理逻辑，将数字值分为整型与浮点型。
                 */
                val dbNum = `in`.nextDouble()

                // 数字超过long的最大值，返回浮点类型
                if (dbNum > Long.MAX_VALUE) {
                    return dbNum
                }

                // 判断数字是否为整数值
                val lngNum = dbNum.toLong()
                if (dbNum == lngNum.toDouble()) {
                    lngNum
                } else {
                    dbNum
                }
            }
            JsonToken.BOOLEAN -> `in`.nextBoolean()
            JsonToken.NULL -> {
                `in`.nextNull()
                null
            }
            else -> throw IllegalStateException()
        }
    }

    @Throws(IOException::class)
    override fun write(out: JsonWriter, value: Any?) {
        // 序列化不处理
    }
}



